home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / stevie.arc / TOS.C < prev    next >
C/C++ Source or Header  |  1990-01-10  |  5KB  |  303 lines

  1. /*
  2.  * System-dependent routines for the Atari ST.
  3.  */
  4.  
  5. #include "stevie.h"
  6.  
  7. #include <osbind.h>
  8.  
  9. /*
  10.  * The following buffer is used to work around a bug in TOS. It appears that
  11.  * unread console input can cause a crash, but only if console output is
  12.  * going on. The solution is to always grab any unread input before putting
  13.  * out a character. The following buffer holds any characters read in this
  14.  * fashion. The problem can be easily produced because STEVIE can't yet keep
  15.  * up with the normal auto-repeat rate in insert mode.
  16.  */
  17. #define    IBUFSZ    128
  18.  
  19. static long inbuf[IBUFSZ];    /* buffer for unread input */
  20. static long *inptr = inbuf;    /* where to put next character */
  21.  
  22. /*
  23.  * inchar() - get a character from the keyboard
  24.  *
  25.  * Certain special keys are mapped to values above 0x80. These
  26.  * mappings are defined in keymap.h. If the key has a non-zero
  27.  * ascii value, it is simply returned. Otherwise it may be a
  28.  * special key we want to map.
  29.  *
  30.  * The ST has a bug involving keyboard input that seems to occur
  31.  * when typing quickly, especially typing capital letters. Sometimes
  32.  * a value of 0x02540000 is read. This doesn't correspond to anything
  33.  * on the keyboard, according to my documentation. My solution is to
  34.  * loop when any unknown key is seen. Normally, the bell is rung to
  35.  * indicate the error. If the "bug" value is seen, we ignore it completely.
  36.  */
  37. int
  38. inchar()
  39. {
  40.     for (;;) {
  41.         long c, *p;
  42.  
  43.         /*
  44.          * Get the next input character, either from the input
  45.          * buffer or directly from TOS.
  46.          */
  47.         if (inptr != inbuf) {    /* input in the buffer, use it */
  48.             c = inbuf[0];
  49.             /*
  50.              * Shift everything else in the buffer down. This
  51.              * would be cleaner if we used a circular buffer,
  52.              * but it really isn't worth it.
  53.              */
  54.             inptr--;
  55.             for (p = inbuf; p < inptr ;p++)
  56.                 *p = *(p+1);
  57.         } else
  58.             c = Crawcin();
  59.     
  60.         if ((c & 0xff) != 0)
  61.             return ((int) c);
  62.     
  63.         switch ((int) (c >> 16) & 0xff) {
  64.     
  65.         case 0x62: return K_HELP;
  66.         case 0x61: return K_UNDO;
  67.         case 0x52: return K_INSERT;
  68.         case 0x47: return K_HOME;
  69.         case 0x48: return K_UARROW;
  70.         case 0x50: return K_DARROW;
  71.         case 0x4b: return K_LARROW;
  72.         case 0x4d: return K_RARROW;
  73.         case 0x29: return K_CGRAVE;    /* control grave accent */
  74.         
  75.         /*
  76.          * Occurs due to a bug in TOS.
  77.          */
  78.         case 0x54:
  79.             break;
  80.         /*
  81.          * Add the function keys here later if we put in support
  82.          * for macros.
  83.          */
  84.     
  85.         default:
  86.             beep();
  87.             break;
  88.     
  89.         }
  90.     }
  91. }
  92.  
  93. /*
  94.  * get_inchars - snarf away any pending console input
  95.  *
  96.  * If the buffer overflows, we discard what's left and ring the bell.
  97.  */
  98. static void
  99. get_inchars()
  100. {
  101.     while (Cconis()) {
  102.         if (inptr >= &inbuf[IBUFSZ]) {    /* no room in buffer? */
  103.             Crawcin();        /* discard the input */
  104.             beep();            /* and sound the alarm */
  105.         } else
  106.             *inptr++ = Crawcin();
  107.     }
  108. }
  109.  
  110. void
  111. outchar(c)
  112. char    c;
  113. {
  114.     get_inchars();
  115.     Cconout(c);
  116. }
  117.  
  118. void
  119. outstr(s)
  120. register char    *s;
  121. {
  122.     get_inchars();
  123.     Cconws(s);
  124. }
  125.  
  126. #define    BGND    0
  127. #define    TEXT    3
  128.  
  129. /*
  130.  * vbeep() - visual bell
  131.  */
  132. static void
  133. vbeep()
  134. {
  135.     int    text, bgnd;        /* text and background colors */
  136.     long    l;
  137.  
  138.     text = Setcolor(TEXT, -1);
  139.     bgnd = Setcolor(BGND, -1);
  140.  
  141.     Setcolor(TEXT, bgnd);        /* swap colors */
  142.     Setcolor(BGND, text);
  143.  
  144.     for (l=0; l < 5000 ;l++)    /* short pause */
  145.         ;
  146.  
  147.     Setcolor(TEXT, text);        /* restore colors */
  148.     Setcolor(BGND, bgnd);
  149. }
  150.  
  151. void
  152. beep()
  153. {
  154.     if (P(P_VB))
  155.         vbeep();
  156.     else
  157.         outchar('\007');
  158. }
  159.  
  160. /*
  161.  * remove(file) - remove a file
  162.  */
  163. void
  164. remove(file)
  165. char *file;
  166. {
  167.     Fdelete(file);
  168. }
  169.  
  170. /*
  171.  * rename(of, nf) - rename existing file 'of' to 'nf'
  172.  */
  173. void
  174. rename(of, nf)
  175. char    *of, *nf;
  176. {
  177.     Fdelete(nf);        /* if 'nf' exists, remove it */
  178.     Frename(0, of, nf);
  179. }
  180.  
  181. void
  182. windinit()
  183. {
  184.     if (Getrez() == 0)
  185.         Columns = 40;        /* low resolution */
  186.     else
  187.         Columns = 80;        /* medium or high */
  188.  
  189.     P(P_LI) = Rows = 25;
  190.  
  191.     Cursconf(1,NULL);
  192. }
  193.  
  194. void
  195. windexit(r)
  196. int r;
  197. {
  198.     exit(r);
  199. }
  200.  
  201. void
  202. windgoto(r, c)
  203. int    r, c;
  204. {
  205.     outstr("\033Y");
  206.     outchar(r + 040);
  207.     outchar(c + 040);
  208. }
  209.  
  210. /*
  211.  * System calls or library routines missing in TOS.
  212.  */
  213.  
  214. void
  215. sleep(n)
  216. int n;
  217. {
  218.     int k;
  219.  
  220.     k = Tgettime();
  221.     while ( Tgettime() <= k+n )
  222.         ;
  223. }
  224.  
  225. void
  226. delay()
  227. {
  228.     long    n;
  229.  
  230.     for (n = 0; n < 8000 ;n++)
  231.         ;
  232. }
  233.  
  234. int
  235. system(cmd)
  236. char    *cmd;
  237. {
  238.     char    arg[1];
  239.  
  240.     arg[0] = (char) 0;    /* no arguments passed to the shell */
  241.  
  242.     if (Pexec(0, cmd, arg, 0L) < 0)
  243.         return -1;
  244.     else
  245.         return 0;
  246. }
  247.  
  248. #ifdef    MEGAMAX
  249. char *
  250. strchr(s, c)
  251. char    *s;
  252. int    c;
  253. {
  254.     do {
  255.         if ( *s == c )
  256.             return(s);
  257.     } while (*s++);
  258.     return(NULL);
  259. }
  260. #endif
  261.  
  262. #ifdef    MEGAMAX
  263.  
  264. FILE *
  265. fopenb(fname, mode)
  266. char    *fname;
  267. char    *mode;
  268. {
  269.     char    modestr[10];
  270.  
  271.     sprintf(modestr, "b%s", mode);
  272.  
  273.     return fopen(fname, modestr);
  274. }
  275.  
  276. #endif
  277.  
  278. /*
  279.  * getenv() - get a string from the environment
  280.  *
  281.  * Both Alcyon and Megamax are missing getenv(). This routine works for
  282.  * both compilers and with the Beckemeyer and Gulam shells. With gulam,
  283.  * the env_style variable should be set to either "mw" or "gu".
  284.  */
  285. char *
  286. getenv(name)
  287. char *name;
  288. {
  289.     extern long _base;
  290.     char *envp, *p;
  291.  
  292.     envp = *((char **) (_base + 0x2c));
  293.  
  294.     for (; *envp ;envp += strlen(envp)+1) {
  295.         if (strncmp(envp, name, strlen(name)) == 0) {
  296.             p = envp + strlen(name);
  297.             if (*p++ == '=')
  298.                 return p;
  299.         }
  300.     }
  301.     return (char *) 0;
  302. }
  303.